import tkinter as tk
from tkinter import messagebox
import subprocess
import threading
from concurrent.futures import ThreadPoolExecutor
import os

class FFmpegDownloader:
    def __init__(self, master):
        self.master = master
        master.title("FFmpeg Downloader")

        self.url_label = tk.Label(master, text="URL:")
        self.url_label.pack()
        self.url_entry = tk.Entry(master, width=50)
        self.url_entry.pack()

        self.output_label = tk.Label(master, text="输出文件名:")
        self.output_label.pack()
        self.output_entry = tk.Entry(master, width=50)
        self.output_entry.pack()

        self.progress_label = tk.Label(master, text="进度:")
        self.progress_label.pack()
        self.progress_var = tk.StringVar()
        self.progress_bar = tk.Label(master, textvariable=self.progress_var)
        self.progress_bar.pack()

        self.execute_button = tk.Button(master, text="执行", command=self.add_task)
        self.execute_button.pack(pady=10)

        self.exit_button = tk.Button(master, text="退出", command=master.quit)
        self.exit_button.pack(pady=10)

        # 创建线程池来管理并发任务
        self.executor = ThreadPoolExecutor(max_workers=5)
        self.futures = []

    def add_task(self):
        url = self.url_entry.get().strip()
        output_filename = self.output_entry.get().strip()
        if url and output_filename:
            # 清空输入框
            self.url_entry.delete(0, tk.END)
            self.output_entry.delete(0, tk.END)

            # 记录历史
            self.log_history(url, output_filename)

            future = self.executor.submit(self.download, url, output_filename)
            self.futures.append(future)
        else:
            messagebox.showwarning("警告", "请输入有效的URL和文件名")

    def log_history(self, url, output_filename):
        with open('history.txt', 'a', encoding='utf-8') as file:
            file.write(f"URL: {url}, 输出文件名: {output_filename}\n")

    def download(self, url, output_filename):
        try:
            output_path = f"{output_filename}.mp4"

            # 后台运行 ffmpeg 命令，并将输出重定向到日志文件
            with open('ffmpeg_log.txt', 'w', encoding='utf-8') as log_file:
                process = subprocess.Popen(
                    ['ffmpeg', '-i', url, '-c', 'copy', output_path, '-progress', 'pipe:1'],
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    bufsize=10**8
                )

                # 启动一个线程来读取进度
                progress_thread = threading.Thread(target=self.read_progress, args=(process.stdout, output_filename))
                progress_thread.start()

                # 等待进程结束
                process.wait()

                # 确保进度线程完成
                progress_thread.join()

                if process.returncode == 0:
                    messagebox.showinfo("成功", "转换完成")
                else:
                    messagebox.showerror("错误", "转换过程中出现问题")
        except Exception as e:
            messagebox.showerror("错误", f"执行FFmpeg时发生错误: {e}")

    def read_progress(self, stdout, output_filename):
        total_time = None
        current_time = None
        duration = None
        for line in iter(stdout.readline, b''):
            line = line.decode('utf-8').strip()
            if 'Duration' in line:
                duration = line.split('Duration: ')[1].split(',')[0]
            elif 'time=' in line:
                current_time = line.split('time=')[1].split(' ')[0]
                if duration and current_time:
                    try:
                        total_seconds = self.parse_time(duration)
                        current_seconds = self.parse_time(current_time)
                        percentage = (current_seconds / total_seconds) * 100
                        self.progress_var.set(f"进度: {percentage:.2f}%")
                        self.master.update_idletasks()  # 更新GUI
                    except ValueError:
                        pass

    def parse_time(self, time_str):
        hours, minutes, seconds = map(float, time_str.split(':'))
        return hours * 3600 + minutes * 60 + seconds

if __name__ == "__main__":
    root = tk.Tk()
    downloader = FFmpegDownloader(root)
    root.mainloop()